package kksoft.kkexpress.resolver;


import java.io.IOException;
import java.io.StringReader;
import java.util.ArrayList;
import java.util.List;
import java.util.Stack;

import static kksoft.kkexpress.resolver.State.*;
import static kksoft.kkexpress.resolver.Type.*;


public class ExpressResolver {

    private static boolean isWhiteSpace(char c) {
        return c == ' ' || c == '\r' || c == '\n' || c == '\t';
    }

    public ResolveContext resolve(String script) throws IOException {
        char[] scriptChars = script.toCharArray();

        Stack<ResolveContext> resolveStack = new Stack<ResolveContext>();
        ResolveContext rootRc = new ResolveContext();
        ResolveContext crc = rootRc; // 当前上下文

        for (int i = 0; i < scriptChars.length; i++) {
            char c = scriptChars[i];
            if (IDLE_STATE.equals(crc.state)) {
                if (isWhiteSpace(c)) continue;

                if (c == '"') {
                    crc.state = QUOTE_STATE;
                    crc.type = STRING_TYPE;
                    continue;
                } else if (c == '(') {
                    crc.type = FUNC_TYPE;

                    ResolveContext nrc = new ResolveContext();
                    crc.child.add(nrc);
                    resolveStack.push(crc);
                    crc = nrc;

                    continue;
                } else if (c == ')') {
                    crc = resolveStack.pop();
                    crc.isResolveFinish = true;
                    // 检查child
                    List<Integer> removeList = new ArrayList<Integer>();
                    for (int j = 0; j < crc.child.size(); j++) {
                        ResolveContext child = crc.child.get(j);
                        if (child.sb.length() == 0) {

                            removeList.add(j);
                        }
                    }
                    for (Integer integer : removeList) {
                        crc.child.remove(integer.intValue());
                    }

                    continue;
                } else if (c == ',') {
                    ResolveContext nrc = new ResolveContext();
                    resolveStack.peek().child.add(nrc);
                    crc = nrc;

                    continue;
                } else {
                    crc.state = LITERAL_STATE;
                    crc.type = LITERAL_TYPE;
                }

            } else if (QUOTE_STATE.equals(crc.state)) { // "..."
                // 转义字符
                if (c == '\\') {
                    i++;
                    c = scriptChars[i];
                } else if (c == '"') {
                    crc.isResolveFinish = true;
                    crc.state = IDLE_STATE;

                    continue;
                }
            } else if (LITERAL_STATE.equals(crc.state)) {
                if (isWhiteSpace(c)) { // TODO 标识符中有空格的会忽略空格, 这是个问题
                    crc.state = IDLE_STATE;
                    continue;
                }

                // 停止符号
                if (c == '(' || c == ')' || c == ',') {
                    i--;
                    crc.state = IDLE_STATE;

                    // 所有的状态需要先恢复到IDLE

                    continue;
                }
            }

            crc.sb.append(c);

        }

        return rootRc;
    }


}
